package com.learn.service.impl;

import com.learn.dao.AccountDao;
import com.learn.dao.impl.AccountDaoImpl;
import com.learn.exception.AppException;
import com.learn.exception.BalanceNotEnoughException;
import com.learn.pojo.Account;
import com.learn.service.AccountService;
import com.learn.util.DaoProxyUtil;
import com.learn.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;

/**
 * @author DJJ_F
 * @version 1.0
 * @date 2025/02/20
 * @description
 */
public class AccountServiceImpl implements AccountService {
//    private AccountDao accountDao = new AccountDaoImpl();
    // 调用工具类实现动态代理，强制类型转换可以使用泛型解决 <T> T getMapper(Class<T> type);
//    private AccountDao accountDao = (AccountDao) DaoProxyUtil.genProxy(SqlSessionUtil.openSession(), AccountDao.class);
    // 幸运的是，SqlSession自己有个getMapper方法可以使用单例模式创建接口类的实体类
    // 底层调用了jdk的动态代理Proxy.newProxyInstance()
    private AccountDao accountDao = SqlSessionUtil.openSession().getMapper(AccountDao.class);
    @Override
    public void transfer(String fromId, String toId, Double money) throws BalanceNotEnoughException, AppException {
        // 为了开启事务防止异常
        SqlSession sqlSession = SqlSessionUtil.openSession();
        // 如果是在这里取的话，后面方法里的sqlSession不是同一个，这样做没用
        // 应该使用ThreadLocal 改造 sqlSessionUtil
        // 判断余额
        Account from = accountDao.selectById(fromId); // 要记得删除对应的代码
        if(from.getBalance() < money) {
            throw new BalanceNotEnoughException("余额不足");
        }
        Account to = accountDao.selectById(toId);
        from.setBalance(from.getBalance() - money);
        to.setBalance(to.getBalance() + money);
        int count = accountDao.update(from);
//        String s = null;
//        s.toString();
        count += accountDao.update(to);
        if(count != 2) {
            // 可以设置回滚
            throw new AppException("交易异常");
        }
        // 在这里统一处理提交和关闭
        sqlSession.commit();
        // 这里close不能移除线程对象，需要改造sqlSessionUtil 再用他的close
        SqlSessionUtil.close();
    }
}
